package com.hm.shopping.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Service;

import com.hm.common.def.DataStatusDef;
import com.hm.common.exception.ErrorCode;
import com.hm.common.exception.ServiceException;
import com.hm.common.su.bean.PageInfo;
import com.hm.common.su.bean.PageInfo.PageInfoParam;
import com.hm.common.util.CommonUtil;
import com.hm.common.util.DateUtil;
import com.hm.common.util.Optional;
import com.hm.shopping.auto.su.BaseDomain;
import com.hm.shopping.def.NewsAnnouncementEnum;
import com.hm.shopping.domain.NewsAnnouncementDomain;
import com.hm.shopping.domain.QNewsAnnouncementDomain;
import com.hm.shopping.repository.NewsAnnouncementRepositry;
import com.hm.shopping.su.BeanUtil;
import com.hm.shopping.vo.NewsAnnouncementVo;
import com.querydsl.core.types.dsl.BooleanExpression;

/**
 * @author shishun.wang
 * @date 2018年1月18日 上午10:47:56
 * @version 1.0
 * @describe
 */
@Service
public class NewsAnnouncementServiceImpl implements NewsAnnouncementService {

	@Autowired
	private NewsAnnouncementRepositry newsAnnouncementRepositry;

	public List<NewsAnnouncementVo> getTopNewsAnnouncement() {
		QNewsAnnouncementDomain qNewsAnnouncementDomain = QNewsAnnouncementDomain.newsAnnouncementDomain;
		Pageable pageable = new QPageRequest(0, 2, qNewsAnnouncementDomain.createTime.desc());

		Page<NewsAnnouncementDomain> page = newsAnnouncementRepositry.findAll(qNewsAnnouncementDomain.status.eq(DataStatusDef.ENABLE).and(qNewsAnnouncementDomain.headlines.eq(false)), pageable);
		return Optional.of(page.getContent()).map(this::fullNewsAnnouncementVo).get();
	}

	private List<NewsAnnouncementVo> fullNewsAnnouncementVo(List<NewsAnnouncementDomain> items) {

		return items.parallelStream().map(item -> {
			NewsAnnouncementVo vo = new NewsAnnouncementVo();
			BeanUtil.copyProperties(item, vo);
			vo.setNewsAnnouncementStr(item.getNewsAnnouncement().desc());
			vo.setCreateTime(DateUtil.data2long(item.getCreateTime()));

			return vo;
		}).collect(Collectors.toList());
	}

	public List<NewsAnnouncementVo> getTopHeadlinesNewsAnnouncement() {
		QNewsAnnouncementDomain qNewsAnnouncementDomain = QNewsAnnouncementDomain.newsAnnouncementDomain;
		Pageable pageable = new QPageRequest(0, 5, qNewsAnnouncementDomain.createTime.desc());

		Page<NewsAnnouncementDomain> page = newsAnnouncementRepositry.findAll(qNewsAnnouncementDomain.status.eq(DataStatusDef.ENABLE).and(qNewsAnnouncementDomain.headlines.eq(true)), pageable);
		return Optional.of(page.getContent()).map(this::fullNewsAnnouncementVo).get();
	}

	@Override
	public void addNewsAnnouncement(NewsAnnouncementVo newsAnnouncementVo) {
		if (CommonUtil.isAnyEmpty(newsAnnouncementVo.getNewsName(), newsAnnouncementVo.getNewsAnnouncement())) {
			throw ServiceException.warning(ErrorCode.REQUIRED_PARAMETERS_MISSING);
		}

		NewsAnnouncementDomain domain = new NewsAnnouncementDomain();
		BeanUtil.copyProperties(newsAnnouncementVo, domain);
		BaseDomain.initBaseInfo(domain);
		newsAnnouncementRepositry.save(domain);
	}

	@Override
	public NewsAnnouncementVo getNewsAnnouncement(String newsAnnouncementId) {
		if (CommonUtil.isEmpty(newsAnnouncementId)) {
			throw ServiceException.warning(ErrorCode.REQUIRED_PARAMETERS_MISSING);
		}

		NewsAnnouncementDomain newsAnnouncementDomain = newsAnnouncementRepositry.findOne(newsAnnouncementId);
		if (CommonUtil.isEmpty(newsAnnouncementDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		NewsAnnouncementVo vo = new NewsAnnouncementVo();
		BeanUtil.copyProperties(newsAnnouncementDomain, vo);
		vo.setNewsAnnouncementStr(newsAnnouncementDomain.getNewsAnnouncement().desc());
		vo.setCreateTime(DateUtil.data2long(newsAnnouncementDomain.getCreateTime()));

		return vo;
	}

	@Override
	public PageInfo<NewsAnnouncementVo> queryNewsAnnouncement(PageInfoParam pageParam, NewsAnnouncementEnum newsAnnouncement, String newsName) {
		QNewsAnnouncementDomain qNewsAnnouncementDomain = QNewsAnnouncementDomain.newsAnnouncementDomain;
		Pageable pageable = new QPageRequest(pageParam.getPage(), pageParam.getSize(), qNewsAnnouncementDomain.createTime.desc());

		BooleanExpression predicate = qNewsAnnouncementDomain.status.eq(DataStatusDef.ENABLE);
		if (CommonUtil.isNotEmpty(newsName)) {
			predicate = predicate.and(qNewsAnnouncementDomain.newsName.like(newsName));
		}

		if (CommonUtil.isNotEmpty(newsAnnouncement)) {
			predicate = predicate.and(qNewsAnnouncementDomain.newsAnnouncement.eq(newsAnnouncement));
		}

		Page<NewsAnnouncementDomain> page = newsAnnouncementRepositry.findAll(predicate, pageable);

		return new PageInfo<NewsAnnouncementVo>(page.getContent().parallelStream().map(item -> {
			NewsAnnouncementVo vo = new NewsAnnouncementVo();
			BeanUtil.copyProperties(item, vo);
			vo.setNewsAnnouncementStr(item.getNewsAnnouncement().desc());
			vo.setCreateTime(DateUtil.data2long(item.getCreateTime()));

			return vo;
		}).collect(Collectors.toList()), page.getTotalPages(), page.getTotalElements());
	}

	@Override
	public void updateNewsAnnouncement(NewsAnnouncementVo newsAnnouncementVo) {
		if (CommonUtil.isAnyEmpty(newsAnnouncementVo.getId(), newsAnnouncementVo.getNewsName(), newsAnnouncementVo.isHeadlines(), newsAnnouncementVo.getNewsAnnouncement())) {
			throw ServiceException.warning(ErrorCode.REQUIRED_PARAMETERS_MISSING);
		}

		NewsAnnouncementDomain newsAnnouncementDomain = newsAnnouncementRepositry.findOne(newsAnnouncementVo.getId());
		if (CommonUtil.isEmpty(newsAnnouncementDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		newsAnnouncementDomain.setNewsName(newsAnnouncementVo.getNewsName());
		newsAnnouncementDomain.setNewsAnnouncement(newsAnnouncementVo.getNewsAnnouncement());
		newsAnnouncementDomain.setHeadlines(newsAnnouncementVo.isHeadlines());
		newsAnnouncementDomain.setIntroduction(newsAnnouncementVo.getIntroduction());
		newsAnnouncementDomain.setContent(newsAnnouncementVo.getContent());

		newsAnnouncementRepositry.save(newsAnnouncementDomain);
	}

	@Override
	public void deleteNewsAnnouncement(String newsAnnouncementId) {
		if (CommonUtil.isEmpty(newsAnnouncementId)) {
			throw ServiceException.warning(ErrorCode.REQUIRED_PARAMETERS_MISSING);
		}

		NewsAnnouncementDomain newsAnnouncementDomain = newsAnnouncementRepositry.findOne(newsAnnouncementId);
		if (CommonUtil.isEmpty(newsAnnouncementDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		newsAnnouncementDomain.setStatus(DataStatusDef.DISABLE);
		newsAnnouncementRepositry.save(newsAnnouncementDomain);
	}

}
